﻿using System;
using System.Windows;
using System.Windows.Input;
using AvalonDock;
using IllSoft.Xvcc.Volano.Client;
using System.Diagnostics;
using System.Windows.Threading;
using System.Windows.Documents;
using System.Windows.Controls;
using System.Windows.Media;
using System.Collections.Specialized;

namespace IllSoft.Xvcc.WpfUI
{
    /// <summary>
    /// Interaction logic for ChannelWindow.xaml
    /// </summary>
    public partial class ChannelWindow : DocumentContent, IChatWindow
    {
        #region IChatWindow Members

        public event EventHandler<LogEventArgs> Log;

        public event EventHandler<NewDocumentEventArgs> NewDocumentRequired;

        #endregion

        public ChannelWindow()
        {
            InitializeComponent();
        }

        public ChannelWindow(Channel channel)
            : this()
        {
            this._channel = channel;

            this._channel.Joined += new EventHandler<ChannelEventArgs>(_channel_Joined);
            this._channel.Message += new EventHandler<MessageEventArgs>(_channel_Message);
            this._channel.Parted += new EventHandler<PartEventArgs>(_channel_Parted);
            this._channel.Query += new EventHandler<QueryEventArgs>(_channel_Query);
            this._channel.UserListReceived += new EventHandler<UserListEventArgs>(_channel_UserListReceived);

            this._channel.Join();

            //TODO: Need to check out why this doesn't work
            this.usersListView.ItemsSource = this._channel.Users;

            this.Title = this._channel.Name;

            this._idleTimer = new DispatcherTimer(ChannelWindow.GetRandomTimeSpan(), DispatcherPriority.Normal, myCallback, this.Dispatcher);
            this._idleTimer.Stop();
        }

        private void myCallback(object sender, EventArgs e)
        {
            this.SendMessage(ChannelWindow.GetRandomMessage());

            this._idleTimer.Interval = ChannelWindow.GetRandomTimeSpan();
        }

        private static string GetRandomMessage()
        {
            StringCollection messages = Properties.Settings.Default.IdleWords;

            return messages[new Random().Next(messages.Count - 1)];
        }

        private static TimeSpan GetRandomTimeSpan()
        {
            Random random = new Random();
            //return new TimeSpan(0, random.Next(10, 25), random.Next(0, 59));
            return new TimeSpan(0, 0, random.Next(0, 10));
        }

        private Channel _channel;
        private DispatcherTimer _idleTimer;

        void _channel_Joined(object sender, ChannelEventArgs e)
        {
            if (e.EventDetails == EventDetails.Someone)
            {
                this.AppendToRtf("User joined: " + e.User.Nick);
            }
            else
            {
                this.AppendToRtf(string.Format("I joined the channel '{0}'", e.Channel.Name));
            }
        }

        void _channel_Message(object sender, MessageEventArgs e)
        {
            this.AppendToRtf(e.User.Nick + ": " + e.Message);
        }

        void _channel_Parted(object sender, PartEventArgs e)
        {
            if (e.EventDetails == EventDetails.Someone)
            {
                this.AppendToRtf("User left: " + e.User.Nick);
            }
            else if (e.EventDetails == EventDetails.Myself)
            {
                this.AppendToRtf("I left the channel. Idle kick?");
            }
        }

        void _channel_Query(object sender, QueryEventArgs e)
        {
            this.OnLog(new LogEventArgs(string.Format("Query received from '{0}'", e.OtherUser)));
        }

        void _channel_UserListReceived(object sender, UserListEventArgs e)
        {
            this.usersListView.ItemsSource = this._channel.Users;
        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            this._channel.Part();
        }

        private void messageTextBox_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Return)
            {
                this.SendMessage();
            }
        }

        private void AppendToRtf(string text)
        {
            Paragraph p = new Paragraph();
            p.Inlines.Add("[" + DateTime.Now.ToLongTimeString() + "] " + text);

            this.AppendToRtf(p);
        }

        private void AppendToRtf(Block block)
        {
            this.messagesRichTextBox.Document.Blocks.Add(block);
            this.messagesRichTextBox.ScrollToEnd();
        }

        private void SendMessage()
        {
            this.SendMessage(this.messageTextBox.Text);
            this.messageTextBox.Clear();
        }

        private void SendMessage(string message)
        {
            if (message.Length > 0)
            {
                this._channel.SendMessage(message);
                //this.AppendToRtf(string.Format("<{0}> {1}", this._channel.Myself.Nick, message));

                Paragraph para = new Paragraph();
                TextBlock textBlock = new TextBlock(new Run(string.Format("<{0}> {1}", this._channel.Myself.Nick, message)));
                // TODO: Use StaticResource(s)
                //textBlock.Foreground = new BrushConverter().ConvertFromString("#e7ebce") as Brush;
                para.Inlines.Add(textBlock);

                this.AppendToRtf(para);
            }
        }

        protected virtual void OnLog(LogEventArgs e)
        {
            EventHandler<LogEventArgs> handler = this.Log;

            if (handler != null)
            {
                handler(this, e);
            }
        }

        protected virtual void OnNewDocumentRequired(NewDocumentEventArgs e)
        {
            EventHandler<NewDocumentEventArgs> handler = this.NewDocumentRequired;

            if (handler != null)
            {
                handler(this, e);
            }
        }

        private void antiIdleTimerCheckBox_Checked(object sender, RoutedEventArgs e)
        {
            if (this._idleTimer.IsEnabled)
            {
                this._idleTimer.Stop();
            }
            else
            {
                this._idleTimer.Interval = ChannelWindow.GetRandomTimeSpan();
                this._idleTimer.Start();
            }
        }
    }
}
